// 版权所有2011 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// go:build（！cgo&&！windows&&！plan9）| | android | |（osusergo&&！windows&&！plan9）

package user

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
)

func current() (*User, error) {
	uid := currentUID()
	// /$USER和/etc/passwd可能不同意；如果可以的话，我们更喜欢后者。
	// 有关更多信息，请参阅第27524期。
	u, err := lookupUserId(uid)
	if err == nil {
		return u, nil
	}

	homeDir, _ := os.UserHomeDir()
	u = &User{
		Uid:      uid,
		Gid:      currentGID(),
		Username: os.Getenv("USER"),
		Name:     "", // 忽略
		HomeDir:  homeDir,
	}
	// 在Android上，返回一个虚拟用户，而不是失败。
	switch runtime.GOOS {
	case "android":
		if u.Uid == "" {
			u.Uid = "1"
		}
		if u.Username == "" {
			u.Username = "android"
		}
	}
	// cgo不可用，但如果我们发现最小信息
	// 没有它，请使用它：
	if u.Uid != "" && u.Username != "" && u.HomeDir != "" {
		return u, nil
	}
	var missing string
	if u.Username == "" {
		missing = "$USER"
	}
	if u.HomeDir == "" {
		if missing != "" {
			missing += ", "
		}
		missing += "$HOME"
	}
	return u, fmt.Errorf("user: Current requires cgo or %s set in environment", missing)
}

func currentUID() string {
	if id := os.Getuid(); id >= 0 {
		return strconv.Itoa(id)
	}
	// 注意：Windows返回-1，但该文件在
	// Windows上不使用，因此不应使用此空返回路径。
	return ""
}

func currentGID() string {
	if id := os.Getgid(); id >= 0 {
		return strconv.Itoa(id)
	}
	return ""
}
